using System;
using System.IO;
using System.Xml;
using System.Drawing;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Globalization;
using System.Collections.Specialized;
using System.Runtime.InteropServices;

namespace HongShijin.PrintActiveX
{
	public class PrintItem
	{
		public const string TOP = "top";
		public const string LEFT = "left";
		public const string WIDTH = "width";
		public const string HEIGHT = "height";
		public const string VALUE = "value";
		public const string DEFAULT = "default";
		public const string COLOR = "color";
		public const string PRINT = "print";
		public const string KEY = "key";
		public const string FACE = "face";
		public const string SIZE = "size";
		public const string STYLE = "style";

		public const string TYPE_ARC = "arc";
		public const string TYPE_TEXT = "text";
		public const string TYPE_LINE = "line";
		public const string TYPE_IMAGE = "image";
		public const string TYPE_PAGER = "pager";
		public const string TYPE_SETTING = "setting";
		public const string TYPE_RECTANGLE = "rectangle";

		protected float _Left;
		protected float _Top;
		protected float _Width;
		protected float _Height;
		protected float _Size;
		protected Color _Color;
		protected string _Key;
		protected string _Face;
		protected string _Value;
		protected string _Default;
		protected int _Style;
		protected bool _Print;
		protected EItemType _Type;

		public PrintItem(PrintItem pager, List<PrintItem> list, XmlNode node)
		{
			int i = 0;
			bool b = false;
			float fA = -1;
			float fB = -1;
			decimal d = -1;
			PrintItem item = null;
			//Key
			string t = GetValue(node, KEY);
			if (list != null && list.Count > 0)
			{
				for (i = list.Count - 1; i >= 0; i--)
				{
					if (list[i] == null)
						break;

					if (list[i].Key == t)
					{
						item = list[i];
						break;
					}
				}
				if (item == null)
					item = list[list.Count - 1];
			}
			if (item == null || string.IsNullOrEmpty(item.Key) || (!string.IsNullOrEmpty(t) && item.Key != t))
				this._Key = t;
			else
				this._Key = item.Key;
			//Type
			this._Type = TestType(node);
			//Top
			if (pager != null)
			{
				fA = pager.Top;
				fB = pager.Height;
			}
			if (item != null)
				d = new decimal(item.Top);
			this._Top = decimal.ToSingle(GetNumber(new decimal(fA), new decimal(fB), d, GetValue(node, TOP)));
			//Left
			if (pager != null)
			{
				fA = pager.Left;
				fB = pager.Width;
			}
			if (item != null)
				d = new decimal(item.Left);
			this._Left = decimal.ToSingle(GetNumber(new decimal(fA), new decimal(fB), d, GetValue(node, LEFT)));
			//Width
			if (pager != null)
			{
				fA = -1;
				fB = pager.Width;
			}
			if (item != null)
				d = new decimal(item.Width);
			this._Width = decimal.ToSingle(GetNumber(new decimal(fA), new decimal(fB), d, GetValue(node, WIDTH)));
			//Height
			if (pager != null)
			{
				fA = -1;
				fB = pager.Height;
			}
			if (item != null)
				d = new decimal(item.Height);
			this._Height = decimal.ToSingle(GetNumber(new decimal(fA), new decimal(fB), d, GetValue(node, HEIGHT)));
			//Size
			if (pager != null)
			{
				fA = -1;
				fB = pager.Size;
			}
			if (item != null)
				d = new decimal(item.Size);
			this._Size = decimal.ToSingle(GetNumber(new decimal(fA), new decimal(fB), d, GetValue(node, SIZE)));
			//Color
			if (item != null)
				this._Color = Common.ParseColor(GetValue(node, COLOR), item.ForeColor);
			else if (pager != null)
				this._Color = Common.ParseColor(GetValue(node, COLOR), pager.ForeColor);
			else
				this._Color = Common.ParseColor(GetValue(node, COLOR));
			//Face
			if (item != null)
				this._Face = GetValue(node, FACE, item.Face);
			else if (pager != null)
				this._Face = GetValue(node, FACE, pager.Face);
			else
				this._Face = GetValue(node, FACE);
			//Value
			this._Value = GetValue(node, VALUE);
			if (string.IsNullOrEmpty(this._Value))
				this._Value = node.InnerText;
			//if (string.IsNullOrEmpty(this._Value))
			//{
			//    if (item != null)
			//        this._Value = GetValue(node, VALUE, item._Value);
			//    else if (pager != null)
			//        this._Value = GetValue(node, VALUE, pager._Value);
			//}
			//Default
			this._Default = GetValue(node, DEFAULT);
			//if (item != null)
			//    this._Default = GetValue(node, DEFAULT, item._Default);
			//else if (pager != null)
			//    this._Default = GetValue(node, DEFAULT, pager._Default);
			//else
			//    this._Default = GetValue(node, DEFAULT);
			//
			t = GetValue(node, STYLE);
			if (string.IsNullOrEmpty(t))
				this._Style = 0;
			else
			{
				t = t.ToLower();
				if (int.TryParse(t, out i))
					this._Style = i;
				else if (t == "underline")
					this._Style = (int)FontStyle.Underline;
				else if (t == "strikeout")
					this._Style = (int)FontStyle.Strikeout;
				else if (t == "regular")
					this._Style = (int)FontStyle.Regular;
				else if (t == "italic")
					this._Style = (int)FontStyle.Italic;
				//else if (t == "bold")
				//    this._Style = (int)FontStyle.Bold;
				else
					this._Style = (int)FontStyle.Bold;
			}
			//
			t = GetValue(node, PRINT);
			if (string.IsNullOrEmpty(t))
			{
				this._Print = true;
			}
			else
			{
				t = t.ToLower();
				if (bool.TryParse(t, out b))
					this._Print = b;
				else if (decimal.TryParse(t, out d))
					this._Print = (d != 0);
				else if (t == "on" || t == "yes" || t == "y" || t == "true" || t == "t")
					this._Print = true;
				else
					this._Print = false;
			}
		}

		public float Top
		{
			get
			{
				return this._Top;
			}
		}

		public float Left
		{
			get
			{
				return this._Left;
			}
		}

		public float Width
		{
			get
			{
				return this._Width;
			}
		}

		public float Height
		{
			get
			{
				return this._Height;
			}
		}

		public float Size
		{
			get
			{
				return this._Size;
			}
		}

		public Color ForeColor
		{
			get
			{
				return this._Color;
			}
		}

		public string Key
		{
			get
			{
				return this._Key;
			}
		}

		public string Face
		{
			get
			{
				return this._Face;
			}
		}

		public string Value
		{
			set
			{
				this._Value = value;
			}
			get
			{
				if (string.IsNullOrEmpty(this._Value))
					return this._Default;

				return this._Value;
			}
		}

		public int Style
		{
			get
			{
				return this._Style;
			}
		}

		public bool Print
		{
			get
			{
				return this._Print;
			}
		}

		public EItemType Type
		{
			get
			{
				return this._Type;
			}
		}

		public Font GetFont()
		{
			int i = decimal.ToInt32(new decimal(this._Size));
			if (i <= 0)
				i = 12;
			if (string.IsNullOrEmpty(this._Face))
				return new Font(FontFamily.Families[0], i, (FontStyle)this._Style);

			try
			{
				return new Font(this._Face, i, (FontStyle)this._Style);
			}
			catch// (Exception x)
			{
				return new Font(FontFamily.Families[0], i, (FontStyle)this._Style);
			}
		}

		private static string GetValue(XmlNode node, string name)
		{
			return GetValue(node, name, string.Empty);
		}
		private static string GetValue(XmlNode node, string name, string nullValue)
		{
			int i;
			string t;
			if (string.IsNullOrEmpty(name) || node == null)
				return nullValue;

			name = name.ToLower();
			for (i = 0; i < node.Attributes.Count; i++)
			{
				if (node.Attributes[i].Name.ToLower() == name)
				{
					t = node.Attributes[i].Value;
					if (t.Trim().ToLower().IndexOf("xpath:") == 0)
					{
						t = t.Trim().Substring(6).Trim();
						if (t[0] == '.')
							node = node.SelectSingleNode(t.Substring(2));
						else if (t[0] == '/')
							node = node.OwnerDocument.SelectSingleNode(t);
						else
							node = node.OwnerDocument.DocumentElement.SelectSingleNode(t);
						if (node is XmlAttribute)
							return node.Value;

						return node.InnerText;
					}

					return t;
				}
			}

			for (i = 0; i < node.ChildNodes.Count; i++)
			{
				if (node.ChildNodes[i].Name.ToLower() == name)
				{
					t = node.ChildNodes[i].InnerText;
					if (t.Trim().ToLower().IndexOf("xpath:") == 0)
					{
						t = t.Trim().Substring(6).Trim();
						if (t[0] == '.')
							node = node.SelectSingleNode(t.Substring(2));
						else if (t[0] == '/')
							node = node.OwnerDocument.SelectSingleNode(t);
						else
							node = node.OwnerDocument.DocumentElement.SelectSingleNode(t);
						if (node is XmlAttribute)
							return node.Value;

						return node.InnerText;
					}

					return t;
				}
			}

			return nullValue;
		}

		private static decimal GetNumber(decimal origin, decimal verge, decimal relatively, string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				if (relatively >= 0)
					return relatively;

				if (origin >= 0)
					return origin;

				if (verge >= 0)
					return verge;

				return decimal.Zero;
			}

			char c = '\0';
			if (value[0] == '%' || value[value.Length - 1] == '%')
				c = '%';
			if (value[0] == '+' || value[value.Length - 1] == '+')
				c = '+';
			if (value[0] == '-' || value[value.Length - 1] == '-')
				c = '-';
			if (value[0] == '*' || value[value.Length - 1] == '*')
				c = '*';
			if (value[0] == '/' || value[value.Length - 1] == '/')
				c = '/';
			value = Regex.Replace(value, @"\D+", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
			decimal d;
			if (!decimal.TryParse(value, out d))
			{
				if (relatively >= 0)
					return relatively;

				if (origin >= 0)
					return origin;

				if (verge >= 0)
					return verge;

				return decimal.Zero;
			}

			if (c == '%')
			{
				if (verge >= 0 && origin >= 0)
					return d * verge / 100 + origin;

				if (verge >= 0)
					return d * verge / 100;

				return decimal.Zero;
			}

			if (c == '+')
			{
				if (relatively >= 0)
					return relatively + d;

				if (origin >= 0)
					return origin + d;

				if (verge >= 0)
					return verge + d;

				return d;
			}

			if (c == '-')
			{
				if (relatively >= 0)
					return relatively - d;

				if (origin >= 0)
					return origin - d;

				if (verge >= 0)
					return verge - d;

				return d;
			}

			if (c == '*')
			{
				if (relatively >= 0)
					return relatively * d;

				if (origin >= 0)
					return origin * d;

				if (verge >= 0)
					return verge * d;

				return d;
			}

			if (c == '/')
			{
				if (relatively >= 0 && d != 0)
					return relatively / d;

				if (origin >= 0 && d != 0)
					return origin / d;

				if (verge >= 0 && d != 0)
					return verge / d;

				return d;
			}

			if (origin >= 0)
				return origin + d;

			return d;
		}

		public static EItemType TestType(XmlNode node)
		{
			string t = node.Name.ToLower();
			if (t == TYPE_ARC)
				return EItemType.Arc;

			if (t == TYPE_TEXT)
				return EItemType.Text;

			if (t == TYPE_LINE)
				return EItemType.Line;

			if (t == TYPE_IMAGE)
				return EItemType.Image;

			if (t == TYPE_PAGER)
				return EItemType.Pager;

			if (t == TYPE_SETTING)
				return EItemType.Setting;

			if (t == TYPE_RECTANGLE)
				return EItemType.Rectangle;

			return EItemType.Unknow;//.Setting;//.Pager;
		}
	}
}
